package com.tools.app;

import android.util.Log;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;

/**
 * 日志工具类
 *
 * @author sugarzhang
 */
public class LogUtil {
    // 基本数据类型
    private final static String[] types = {"int", "java.lang.String", "boolean", "char",
            "float", "double", "long", "short", "byte"};

    /**
     * 异常栈位移
     */
    private static final int EXCEPTION_STACK_INDEX = 2;
    private static final SimpleDateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 日志级别
     */
//    public static int LOG_LEVEL = Log.ERROR + 1;

    public static int LOG_LEVEL = 1;

    /**
     * verbose级别的日志
     *
     * @param msg 打印内容
     * @see [类、类#方法、类#成员]
     */
    public static void verbose(String msg) {
        if (Log.VERBOSE >= LOG_LEVEL) {
            Log.v(getTag(), msg);
        }
    }

    /**
     * debug级别的日志
     *
     * @param msg 打印内容
     * @see [类、类#方法、类#成员]
     */
    public static void debug(String msg) {
        if (Log.DEBUG >= LOG_LEVEL) {
            Log.d(getTag(), msg);
        }
    }

    /**
     * info级别的日志
     *
     * @param msg 打印内容
     * @see [类、类#方法、类#成员]
     */
    public static void info(String msg) {
        if (Log.INFO >= LOG_LEVEL) {
            Log.i(getTag(), msg);
        }
    }

    /**
     * warn级别的日志
     *
     * @param msg 打印内容
     * @see [类、类#方法、类#成员]
     */
    public static void warn(String msg) {
        if (Log.WARN >= LOG_LEVEL) {
            Log.w(getTag(), msg);
        }
    }

    /**
     * error级别的日志
     *
     * @param msg 打印内容
     * @see [类、类#方法、类#成员]
     */
    public static void error(String msg) {
        if (Log.ERROR >= LOG_LEVEL) {
            String tag = getTag();
            Log.e(tag, msg);
        }
    }

    public static void error(String msg, Throwable tr) {
        if (Log.ERROR >= LOG_LEVEL) {
            String tag = getTag();
            Log.e(tag, msg, tr);
        }
    }

    /**
     * 获取日志的标签 格式：类名_方法名_行号 （需要权限：android.permission.GET_TASKS）
     *
     * @return tag
     * @see [类、类#方法、类#成员]
     */
    private static String getTag() {
        try {
            Exception exception = new LogException();
            if (exception.getStackTrace() == null || exception.getStackTrace().length <= EXCEPTION_STACK_INDEX) {
                return "***";
            }
            StackTraceElement element = exception.getStackTrace()[EXCEPTION_STACK_INDEX];

            String className = element.getClassName();

            int index = className.lastIndexOf(".");
            if (index > 0) {
                className = className.substring(index + 1);
            }

            return className + "_" + element.getMethodName() + "_" + element.getLineNumber();

        } catch (Throwable e) {
            e.printStackTrace();
            return "***";
        }
    }

    /**
     * 取日志标签用的的异常类，只是用于取得日志标签
     */
    private static class LogException extends Exception {
        /**
         * 注释内容
         */
        private static final long serialVersionUID = 1L;
    }

    /**
     * 将对象转化为String
     *
     * @param object
     * @return
     */
    public static <T> String objectToString(T object) {
        if (object == null) {
            return "Object{object is null}";
        }
        if (object.toString().startsWith(object.getClass().getName() + "@")) {
            StringBuilder builder = new StringBuilder(object.getClass().getSimpleName() + "{");
            Field[] fields = object.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                boolean flag = false;
                for (String type : types) {
                    if (field.getType().getName().equalsIgnoreCase(type)) {
                        flag = true;
                        Object value = null;
                        try {
                            value = field.get(object);
                        } catch (IllegalAccessException e) {
                            value = e;
                        } finally {
                            builder.append(String.format("%s=%s, ", field.getName(),
                                    value == null ? "null" : value.toString()));
                            break;
                        }
                    }
                }
                if (!flag) {
                    builder.append(String.format("%s=%s, ", field.getName(), "Object"));
                }
            }
            return builder.replace(builder.length() - 2, builder.length() - 1, "}").toString();
        } else {
            return object.toString();
        }
    }
}
